package pl.extremme.robocode.utils;

/**
 *
 * @author XyC
 */
public class CoordinateUtils {

    public CoordinateUtils() {
    }

    static PolarPoint CartesianToPolar(CartesianPoint p_Base, CartesianPoint p_Other) {
        CartesianPoint delta = CoordinateUtils.GetDelta(p_Base, p_Other);
        double distance = Math.sqrt(Math.pow(delta.getX(), 2) + Math.pow(delta.getY(), 2));
        double angle;
        if(delta.getX() > 0) {
            if(delta.getY() > 0) {
                angle = Math.asin(delta.getX() / distance); // I
            } else if (delta.getY() < 0) {
                angle = Math.PI - Math.asin(delta.getX() / distance); // II
            } else {
                angle = Math.PI / 2; // E
            }
        } else if (delta.getX() < 0) {
            if(delta.getY() > 0) {
                angle = 2 * Math.PI + Math.asin(delta.getX() / distance); // IV
            } else if (delta.getY() < 0) {
                angle = Math.PI - Math.asin(delta.getX() / distance); // III
            } else {
                angle = 3 * Math.PI / 2; // W
            }
        } else {
            if(delta.getY() > 0) {
                angle = 0; // N
            } else if (delta.getY() < 0) {
                angle = Math.PI; // S
            } else {
                angle = 0;
            }
        }
        return new PolarPoint(distance, angle);
    }

    static CartesianPoint PolarToCartesian(CartesianPoint p_Base, PolarPoint p_Other) {
        CartesianPoint delta = CoordinateUtils.GetDelta(p_Base, p_Other);
        return new CartesianPoint(p_Base.getX() + delta.getX(), p_Base.getY() + delta.getY());
    }

    static CartesianPoint GetDelta(CartesianPoint p_Base, CartesianPoint p_To) {
        return new CartesianPoint(p_To.getX() - p_Base.getX(), p_To.getY() - p_Base.getY());
    }

    static CartesianPoint GetDelta(CartesianPoint p_Base, PolarPoint p_To) {
        double dx = Math.sin(p_To.getAngle()) * p_To.getDistance();
        double dy = Math.cos(p_To.getAngle()) * p_To.getDistance();
        return new CartesianPoint(dx, dy);
    }

}
